package box.interview.wx.miniapp.controller;

import box.interview.wx.miniapp.config.ApplicationConfig;
import box.interview.wx.miniapp.entity.WxMiniappInterview;
import box.interview.wx.miniapp.mapper.WxMiniappInterviewMapper;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 收藏相关
 */
@RestController
@RequestMapping(value = "/com/wx/collect")
public class CollectController {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private ApplicationConfig applicationConfig;

    @Autowired
    private WxMiniappInterviewMapper wxMiniappInterviewMapper;

    /**
     * 操作收藏，增加收藏，取消收藏
     *
     * @param request
     * @param interviewId
     */
    @GetMapping("toOperateCollect")
    public ResponseEntity toOperateCollect(HttpServletRequest request, Long interviewId, Integer type) {
        // token -> openid
        String skey2openid = applicationConfig.skey2openid;
        // openid -> interview
        String openid2interviewId = applicationConfig.openid2interviewId;

        String token = request.getHeader("token");
        Object obj = redisTemplate.opsForHash().get(skey2openid, token);
        if (obj != null) {
            String openid = (String) obj;
            Object collectObj = redisTemplate.opsForHash().get(openid2interviewId, openid);
            if (collectObj == null) {
                if (type == 1) {
                    // 收藏
                    Map<Long, Long> collectMap = new HashMap<>();
                    collectMap.put(interviewId, 0L);
                    redisTemplate.opsForHash().put(openid2interviewId, openid, JSON.toJSONString(collectMap));
                    // TODO 排行榜+1
                    operateCollectRanking(interviewId, 1);
                }
            } else {
                Map<Long, Long> collectMap = JSON.parseObject(collectObj.toString(), new TypeReference<Map<Long, Long>>() {
                });
                if (type == 1) {
                    // 收藏
                    collectMap.put(interviewId, 0L);
                    // TODO 排行榜+1
                    operateCollectRanking(interviewId, 1);
                }
                if (type == 2) {
                    // 取消收藏
                    collectMap.remove(interviewId);
                    // TODO 排行榜-1
                    operateCollectRanking(interviewId, -1);
                }
                redisTemplate.opsForHash().put(openid2interviewId, openid, JSON.toJSONString(collectMap));
            }
            return ResponseEntity.status(HttpStatus.OK).body(null);
        } else {
            // 重新登录
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
        }
    }

    /**
     * 操作排行榜
     *
     * @param interviewId
     * @param score
     */
    public void operateCollectRanking(Long interviewId, Integer score) {
        String collect2ranking = applicationConfig.collect2ranking;
        redisTemplate.opsForZSet().incrementScore(collect2ranking, "interview-" + interviewId, score);
    }

    /**
     * 查询收藏排行榜
     *
     * @param request
     */
    @GetMapping("getDataCollectRanking")
    public ResponseEntity getDataCollectRanking(HttpServletRequest request, Integer size) {
        String collect2ranking = applicationConfig.collect2ranking;
        // 从大到小查询
        List<Long> interviewIdList = new ArrayList<>();
        Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeByScoreWithScores(collect2ranking, 0, Integer.MAX_VALUE, 0, size);
        for (ZSetOperations.TypedTuple<String> item : set) {
            String value = item.getValue();
            if (value != null && value.length() > 0) {
                String interviewIdStr = value.split("-")[1];
                Long interviewId = Long.valueOf(interviewIdStr);
                interviewIdList.add(interviewId);
            }
        }
        QueryWrapper<WxMiniappInterview> wrapper = new QueryWrapper<>();
        wrapper.in("id", interviewIdList);
        List<WxMiniappInterview> list = wxMiniappInterviewMapper.selectList(wrapper);
        return ResponseEntity.status(HttpStatus.OK).body(list);
    }

    /**
     * 查询我的收藏
     *
     * @param request
     */
    @GetMapping("getDataMyCollect")
    public ResponseEntity getDataMyCollect(HttpServletRequest request) {
        // token -> openid
        String skey2openid = applicationConfig.skey2openid;
        // openid -> interview
        String openid2interviewId = applicationConfig.openid2interviewId;

        String token = request.getHeader("token");
        Object obj = redisTemplate.opsForHash().get(skey2openid, token);
        if (obj != null) {
            String openid = (String) obj;
            // interviewId 的 map集合
            Object collectObj = redisTemplate.opsForHash().get(openid2interviewId, openid);
            if (collectObj == null) {
                return ResponseEntity.status(HttpStatus.OK).body(new ArrayList<>());
            } else {
                Map<Long, Long> collectMap = JSON.parseObject(collectObj.toString(), new TypeReference<Map<Long, Long>>() {
                });
                if (collectMap == null || collectMap.isEmpty()) {
                    return ResponseEntity.status(HttpStatus.OK).body(new ArrayList<>());
                } else {
                    // interviewId 集合
                    Set<Long> interviewIdSet = collectMap.keySet();
                    if (interviewIdSet.isEmpty()) {
                        return ResponseEntity.status(HttpStatus.OK).body(new ArrayList<>());
                    } else {
                        QueryWrapper<WxMiniappInterview> wrapper = new QueryWrapper<>();
                        wrapper.in("id", interviewIdSet);
                        List<WxMiniappInterview> list = wxMiniappInterviewMapper.selectList(wrapper);
                        return ResponseEntity.status(HttpStatus.OK).body(list);
                    }
                }
            }
        } else {
            // 重新登录
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
        }
    }

}
